<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
	<title>top_hits 聚合 | ElasticSearch 7.7 权威指南中文版</title>
	<meta name="keywords" content="ElasticSearch 权威指南中文版, elasticsearch 7, es7, 实时数据分析，实时数据检索" />
    <meta name="description" content="ElasticSearch 权威指南中文版, elasticsearch 7, es7, 实时数据分析，实时数据检索" />
    <!-- Give IE8 a fighting chance -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
	<link rel="stylesheet" type="text/css" href="../static/styles.css" />
	<script>
	var _link = 'search-aggregations-metrics-top-hits-aggregation.html';
    </script>
</head>
<body>
<div class="main-container">
    <section id="content">
        <div class="content-wrapper">
            <section id="guide" lang="zh_cn">
                <div class="container">
                    <div class="row">
                        <div class="col-xs-12 col-sm-8 col-md-8 guide-section">
                            <div style="color:gray; word-break: break-all; font-size:12px;">原英文版地址: <a href="https://www.elastic.co/guide/en/elasticsearch/reference/7.7/search-aggregations-metrics-top-hits-aggregation.html" rel="nofollow" target="_blank">https://www.elastic.co/guide/en/elasticsearch/reference/7.7/search-aggregations-metrics-top-hits-aggregation.html</a>, 原文档版权归 www.elastic.co 所有<br/>本地英文版地址: <a href="../en/search-aggregations-metrics-top-hits-aggregation.html" rel="nofollow" target="_blank">../en/search-aggregations-metrics-top-hits-aggregation.html</a></div>
                        <!-- start body -->
                  <div class="page_header">
<strong>重要</strong>: 此版本不会发布额外的bug修复或文档更新。最新信息请参考 <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html" rel="nofollow">当前版本文档</a>。
</div>
<div id="content">
<div class="breadcrumbs">
<span class="breadcrumb-link"><a href="index.html">Elasticsearch 权威指南 [7.7]</a></span>
»
<span class="breadcrumb-link"><a href="search-aggregations.html">聚合</a></span>
»
<span class="breadcrumb-link"><a href="search-aggregations-metrics.html">度量聚合</a></span>
»
<span class="breadcrumb-node">top_hits 聚合</span>
</div>
<div class="navheader">
<span class="prev">
<a href="search-aggregations-metrics-sum-aggregation.html">« sum 聚合</a>
</span>
<span class="next">
<a href="search-aggregations-metrics-top-metrics.html">top_metrics 聚合 »</a>
</span>
</div>
<div class="section">
<div class="titlepage"><div><div>
<h2 class="title">
<a id="search-aggregations-metrics-top-hits-aggregation"></a>top_hits 聚合
</h2>
</div></div></div>
<p>
<code class="literal">top_hits</code> 度量聚合器跟踪被聚集的最相关的文档。

这个聚合器被用作子聚合器，这样就可以对每个桶聚合最匹配的文档。  
</p>
<p>
<code class="literal">top_hits</code> 聚合器可以有效地用于通过桶聚合器按特定字段对结果集进行分组。

一个或多个桶聚合器决定了将结果集划分到哪些属性中。
</p>
<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_options_2"></a>选项
</h3>
</div></div></div>
<div class="ulist itemizedlist">
<ul class="itemizedlist">
<li class="listitem">
<code class="literal">from</code> - 要获取的第一个结果的偏移量。
</li>
<li class="listitem">
<code class="literal">size</code> - 每个桶返回的最大匹配命中数。默认情况下，会返回前3个匹配项。
</li>
<li class="listitem">
<code class="literal">sort</code> - 命中应该如何排序。默认情况下，命中按主查询的得分排序。
</li>
</ul>
</div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_supported_per_hit_features"></a>单次命中(per hit)支持的功能
</h3>
</div></div></div>
<p>top_hits 聚合返回常规搜索命中，因为可以支持许多单次命中功能:</p>
<div class="ulist itemizedlist">
<ul class="itemizedlist">
<li class="listitem">
<a class="xref" href="search-request-body.html#request-body-search-highlighting" title="Highlighting" rel="nofollow">高亮 (highlighting)</a>
</li>
<li class="listitem">
<a class="xref" href="search-search.html#request-body-search-explain" rel="nofollow">解释 (explain)</a>
</li>
<li class="listitem">
<a class="xref" href="search-request-body.html#request-body-search-queries-and-filters" title="命名查询" rel="nofollow">命名过滤器和查询 (named filters and queries)</a>
</li>
<li class="listitem">
<a class="xref" href="run-a-search.html#source-filtering" title="源过滤" rel="nofollow">源过滤(source filtering)</a>
</li>
<li class="listitem">
<a class="xref" href="search-request-body.html#request-body-search-stored-fields" title="存储的字段" rel="nofollow">存储的字段 (stored fields)</a>
</li>
<li class="listitem">
<a class="xref" href="search-request-body.html#request-body-search-script-fields" title="脚本字段" rel="nofollow">脚本字段(script fields)</a>
</li>
<li class="listitem">
<a class="xref" href="run-a-search.html#docvalue-fields" title="文档值字段" rel="nofollow">文档值字段(doc value fields)</a>
</li>
<li class="listitem">
<a class="xref" href="search-search.html#request-body-search-version" rel="nofollow">包含版本(include versions)</a>
</li>
<li class="listitem">
<a class="xref" href="search-search.html#request-body-search-seq-no-primary-term">包含序列号和主词(include Sequence Numbers and Primary Terms)</a>
</li>
</ul>
</div>
<div class="important admon">
<div class="icon"></div>
<div class="admon_content">
<p>
如果你<span class="strong strong"><strong>只</strong></span>需要<code class="literal">docvalue_fields</code>、<code class="literal">size</code> 和 <code class="literal">sort</code>，那么<a class="xref" href="search-aggregations-metrics-top-metrics.html" title="top_metrics 聚合" rel="nofollow">top_metrics 聚合</a>可能是比 top_hits 聚合更有效率的选择。
</p>
</div>
</div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_example_4"></a>示例
</h3>
</div></div></div>
<p>
在下面的示例中，我们按类型对销售进行分组，并按类型显示最后一笔销售。

对于每笔销售，源中只包含日期和价格字段。
</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">POST /sales/_search?size=0
{
    "aggs": {
        "top_tags": {
            "terms": {
                "field": "type",
                "size": 3
            },
            "aggs": {
                "top_sales_hits": {
                    "top_hits": {
                        "sort": [
                            {
                                "date": {
                                    "order": "desc"
                                }
                            }
                        ],
                        "_source": {
                            "includes": [ "date", "price" ]
                        },
                        "size" : 1
                    }
                }
            }
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/396.console"></div>
<p>响应可能是：</p>
<div class="pre_wrapper lang-console-result">
<pre class="programlisting prettyprint lang-console-result">{
  ...
  "aggregations": {
    "top_tags": {
       "doc_count_error_upper_bound": 0,
       "sum_other_doc_count": 0,
       "buckets": [
          {
             "key": "hat",
             "doc_count": 3,
             "top_sales_hits": {
                "hits": {
                   "total" : {
                       "value": 3,
                       "relation": "eq"
                   },
                   "max_score": null,
                   "hits": [
                      {
                         "_index": "sales",
                         "_type": "_doc",
                         "_id": "AVnNBmauCQpcRyxw6ChK",
                         "_source": {
                            "date": "2015/03/01 00:00:00",
                            "price": 200
                         },
                         "sort": [
                            1425168000000
                         ],
                         "_score": null
                      }
                   ]
                }
             }
          },
          {
             "key": "t-shirt",
             "doc_count": 3,
             "top_sales_hits": {
                "hits": {
                   "total" : {
                       "value": 3,
                       "relation": "eq"
                   },
                   "max_score": null,
                   "hits": [
                      {
                         "_index": "sales",
                         "_type": "_doc",
                         "_id": "AVnNBmauCQpcRyxw6ChL",
                         "_source": {
                            "date": "2015/03/01 00:00:00",
                            "price": 175
                         },
                         "sort": [
                            1425168000000
                         ],
                         "_score": null
                      }
                   ]
                }
             }
          },
          {
             "key": "bag",
             "doc_count": 1,
             "top_sales_hits": {
                "hits": {
                   "total" : {
                       "value": 1,
                       "relation": "eq"
                   },
                   "max_score": null,
                   "hits": [
                      {
                         "_index": "sales",
                         "_type": "_doc",
                         "_id": "AVnNBmatCQpcRyxw6ChH",
                         "_source": {
                            "date": "2015/01/01 00:00:00",
                            "price": 150
                         },
                         "sort": [
                            1420070400000
                         ],
                         "_score": null
                      }
                   ]
                }
             }
          }
       ]
    }
  }
}</pre>
</div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_field_collapse_example"></a>字段折叠示例
</h3>
</div></div></div>
<p>
字段折叠或结果分组是一项功能，它将结果集逻辑地分组，每个组返回前几个文档。

组的排序由组中第一个文档的相关性决定。

在 Elasticsearch 中，这可以通过将一个<code class="literal">top_hits</code>聚合器包裹为子聚合器的桶聚合器来实现。
</p>
<p>
在下面的例子中，我们搜索抓取的网页。

对于每个网页，我们存储网页的 body 及其所属的域(domain)。

通过在 <code class="literal">domain</code> 字段上定义一个 <code class="literal">terms</code> 聚合器，我们按照域对网页的结果集进行分组。

然后将 <code class="literal">top_hits</code> 聚合器定义为子聚合器，这样就可以收集每个桶的匹配命中的前几个。
</p>
<p>
此外，还定义了一个 <code class="literal">max</code> 聚合器，<code class="literal">terms</code>聚合器的排序特性使用该聚合器按照桶中最相关文档的相关性顺序返回桶。
</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">POST /sales/_search
{
  "query": {
    "match": {
      "body": "elections"
    }
  },
  "aggs": {
    "top_sites": {
      "terms": {
        "field": "domain",
        "order": {
          "top_hit": "desc"
        }
      },
      "aggs": {
        "top_tags_hits": {
          "top_hits": {}
        },
        "top_hit" : {
          "max": {
            "script": {
              "source": "_score"
            }
          }
        }
      }
    }
  }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/397.console"></div>
<p>
目前，需要<code class="literal">max</code>(或<code class="literal">min</code>)聚合器来确保来自<code class="literal">terms</code>聚合器的桶根据每个域的最相关网页的分数排序。

不幸的是，<code class="literal">top_hits</code>聚合器还不能用于<code class="literal">terms</code> 聚合器的<code class="literal">order</code>选项。
</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_top_hits_support_in_a_nested_or_reverse_nested_aggregator"></a>嵌套或反向嵌套聚合器中对 top_hits 的支持
</h3>
</div></div></div>
<p>
如果 <code class="literal">top_hits</code> 聚合器包裹在<code class="literal">嵌套(nested)</code>或<code class="literal">反嵌套(reverse_nested)</code>聚合器中，则返回嵌套的命中。

嵌套的命中在某种意义上是隐藏的迷你文档，它们是常规文档的一部分，其中在映射中已经配置了嵌套字段类型。

如果 <code class="literal">top_hits</code> 聚合器被包装在<code class="literal">nested</code>或<code class="literal">reverse_nested</code>聚合器中，那么它能够取消隐藏这些文档。

了解有关<a class="xref" href="nested.html" title="Nested datatype">嵌套类型映射</a>中嵌套的更多信息。
</p>
<p>
如果已经配置了嵌套类型，那么单个文档实际上被索引为多个 Lucene 文档，并且它们共享相同的id。

为了确定嵌套命中的身份，需要的不仅仅是id，这就是为什么嵌套命中还包括它们的嵌套身份。

嵌套标识保存在搜索命中的<code class="literal">_nested</code>字段下，并且包括嵌套命中所属的数组字段和数组字段中的偏移量。

偏移量从零开始。
</p>
<p>
让我们用一个真实的例子来看看它是如何工作的。比如下面这个映射：
</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">PUT /sales
{
    "mappings": {
        "properties" : {
            "tags" : { "type" : "keyword" },
            "comments" : { <a id="CO208-2"></a><i class="conum" data-value="1"></i>
                "type" : "nested",
                "properties" : {
                    "username" : { "type" : "keyword" },
                    "comment" : { "type" : "text" }
                }
            }
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/398.console"></div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO208-1"><i class="conum" data-value="1"></i></a><a href="#CO208-2"></a></p>
</td>
<td align="left" valign="top">
<p>
<code class="literal">comments</code> 是一个数组，它保存 <code class="literal">product</code> 对象下的嵌套文档。
</td>
</tr>
</table>
</div>
<p>并添加几个文档:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">PUT /sales/_doc/1?refresh
{
    "tags": ["car", "auto"],
    "comments": [
        {"username": "baddriver007", "comment": "This car could have better brakes"},
        {"username": "dr_who", "comment": "Where's the autopilot? Can't find it"},
        {"username": "ilovemotorbikes", "comment": "This car has two extra wheels"}
    ]
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/399.console"></div>
<p>
现在可以执行下面的 <code class="literal">top_hits</code> 聚合(包裹在一个 <code class="literal">nested</code> 聚合中):
</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">POST /sales/_search
{
    "query": {
        "term": { "tags": "car" }
    },
    "aggs": {
        "by_sale": {
            "nested" : {
                "path" : "comments"
            },
            "aggs": {
                "by_user": {
                    "terms": {
                        "field": "comments.username",
                        "size": 1
                    },
                    "aggs": {
                        "by_nested": {
                            "top_hits":{}
                        }
                    }
                }
            }
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/400.console"></div>
<p>
具有嵌套命中的前几个命中响应片段，位于数组字段 <code class="literal">comments</code> 的第一个槽中:
</p>
<div class="pre_wrapper lang-console-result">
<pre class="programlisting prettyprint lang-console-result">{
  ...
  "aggregations": {
    "by_sale": {
      "by_user": {
        "buckets": [
          {
            "key": "baddriver007",
            "doc_count": 1,
            "by_nested": {
              "hits": {
                "total" : {
                   "value": 1,
                   "relation": "eq"
                },
                "max_score": 0.3616575,
                "hits": [
                  {
                    "_index": "sales",
                    "_type" : "_doc",
                    "_id": "1",
                    "_nested": {
                      "field": "comments",  <a id="CO209-1"></a><i class="conum" data-value="1"></i>
                      "offset": 0 <a id="CO209-2"></a><i class="conum" data-value="2"></i>
                    },
                    "_score": 0.3616575,
                    "_source": {
                      "comment": "This car could have better brakes", <a id="CO209-3"></a><i class="conum" data-value="3"></i>
                      "username": "baddriver007"
                    }
                  }
                ]
              }
            }
          }
          ...
        ]
      }
    }
  }
}</pre>
</div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO209-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>包含嵌套命中的数组字段的名称</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO209-2"><i class="conum" data-value="2"></i></a></p>
</td>
<td align="left" valign="top">
<p>嵌套命中包含数组时的位置</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO209-3"><i class="conum" data-value="3"></i></a></p>
</td>
<td align="left" valign="top">
<p>嵌套命中的源</p>
</td>
</tr>
</table>
</div>
<p>
如果请求<code class="literal">_source</code>，则只返回嵌套对象的部分源，而不是文档的整个源。

<span class="strong strong"><strong>nested</strong></span> 内部对象级别上的存储字段也可以通过驻留在<code class="literal">nested</code>或<code class="literal">reverse_nested</code>聚合器中的<code class="literal">top_hits</code>聚合器来访问。
</p>
<p>
只有嵌套命中才会在命中中有 <code class="literal">_nested</code> 字段，非嵌套(常规)命中不会有<code class="literal">_nested</code>字段。
</p>
<p>
如果没有启用<code class="literal">_source</code>，那么<code class="literal">_nested</code>中的信息也可以用来解析其他地方的原始源。
</p>
<p>
如果在映射中定义了多级嵌套对象类型，那么<code class="literal">_nested</code>信息也可以是分层的，以便表达两层或更多层的嵌套命中的身份。
</p>
<p>
在下面的示例中，嵌套命中驻留在字段 <code class="literal">nested_grand_child_field</code> 的第一个槽中，然后驻留在<code class="literal">nested_child_field</code>字段的第二个槽中：
</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">...
"hits": {
 "total" : {
     "value": 2565,
     "relation": "eq"
 },
 "max_score": 1,
 "hits": [
   {
     "_index": "a",
     "_type": "b",
     "_id": "1",
     "_score": 1,
     "_nested" : {
       "field" : "nested_child_field",
       "offset" : 1,
       "_nested" : {
         "field" : "nested_grand_child_field",
         "offset" : 0
       }
     }
     "_source": ...
   },
   ...
 ]
}
...</pre>
</div>
</div>

</div>
<div class="navfooter">
<span class="prev">
<a href="search-aggregations-metrics-sum-aggregation.html">« sum 聚合</a>
</span>
<span class="next">
<a href="search-aggregations-metrics-top-metrics.html">top_metrics 聚合 »</a>
</span>
</div>
</div>

                  <!-- end body -->
                        </div>
                        <div class="col-xs-12 col-sm-4 col-md-4" id="right_col">
                        
                        </div>
                    </div>
                </div>
            </section>
        </div>
    </section>
</div>
<script src="../static/cn.js"></script>
</body>
</html>